/*
 *  Copyright 2011 Alexey Andreev.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package org.xthl.core;

import java.util.ArrayList;
import java.util.List;
import org.nop.core.AbstractController;
import org.nop.core.Content;
import org.nop.core.RouteBinding;
import org.nop.util.Injected;
import org.xthl.core.api.MenuCustomItem;
import org.xthl.core.api.MenuItem;
import org.xthl.core.api.MenuLogic;
import org.xthl.core.api.MenuSpecialItem;
import org.xthl.core.lang.ValidationBundle;
import org.xthl.core.view.AcceptRemoveMenuItemView;
import org.xthl.core.view.EditableMenuItemSight;
import org.xthl.core.view.MenuEditForm;
import org.xthl.core.view.MenuEditView;
import org.xthl.core.view.MenuItemEditForm;
import org.xthl.core.view.MenuItemEditView;

/**
 *
 * @author Alexey Andreev
 */
@RouteBinding(MenuRoute.class)
public class MenuController extends AbstractController {
    private MenuLogic logic;
    
    @Injected
    public MenuController(MenuLogic logic) {
        this.logic = logic;
    }

    public Content list(MenuEditForm form) {
        List<EditableMenuItemSight> sightList = new ArrayList<EditableMenuItemSight>();
        for (MenuItem item : logic.getItems()) {
            EditableMenuItemSight sight = new EditableMenuItemSight();
            sight.setId(item.getId());
            sight.setEnabled(item.isEnabled());
            sight.setMoveDownAvailable(true);
            sight.setMoveUpAvailable(true);
            if (item instanceof MenuSpecialItem) {
                MenuSpecialItem special = (MenuSpecialItem)item;
                sight.setTitle(!item.getTitle().isEmpty() ? item.getTitle() :
                        special.getGeneratorType().getName());
                sight.setUrl("");
                sight.setRemovable(false);
            } else if (item instanceof MenuCustomItem) {
                MenuCustomItem custom = (MenuCustomItem)item;
                sight.setTitle(item.getTitle());
                sight.setUrl(custom.getUrl());
                sight.setRemovable(true);
            }
            sightList.add(sight);
        }
        if (!sightList.isEmpty()) {
            sightList.get(0).setMoveUpAvailable(false);
            sightList.get(sightList.size() - 1).setMoveDownAvailable(false);
        }
        return html(createView(MenuEditView.class)
                .setForm(form)
                .setItems(sightList));
    }
    
    public Content enable(MenuEditForm form) {
        logic.enableItems(form.getSelectedItemIds(), true);
        return list(form);
    }
    
    public Content moveUp(MenuEditForm form) {
        Integer itemId = form.getAffectedItemId();
        if (itemId == null) {
            return null;
        }
        MenuItem item = logic.getItem(itemId);
        if (item == null) {
            return null;
        }
        if (item.getPosition() > 0) {
            logic.moveItem(itemId, item.getPosition() - 1);
        }
        return list(form);
    }
    
    public Content moveDown(MenuEditForm form) {
        Integer itemId = form.getAffectedItemId();
        if (itemId == null) {
            return null;
        }
        MenuItem item = logic.getItem(itemId);
        if (item == null) {
            return null;
        }
        int maxPosition = 0;
        for (MenuItem otherItem : logic.getItems()) {
            maxPosition = Math.max(maxPosition, otherItem.getPosition());
        }
        if (item.getPosition() < maxPosition) {
            logic.moveItem(itemId, item.getPosition() + 1);
        }
        return list(form);
    }
    
    public Content edit(MenuItemEditForm form, int itemId) {
        MenuItem item = logic.getItem(itemId);
        if (item == null) {
            return null;
        }
        if (!form.isPosted()) {
            form.setTitle(item.getTitle());
            if (item instanceof MenuCustomItem) {
                MenuCustomItem custom = (MenuCustomItem)item;
                form.setUrl(custom.getUrl());
            }
        }
        return html(createView(MenuItemEditView.class)
                .setForm(form)
                .setItem(item)
                .setRemovable(item instanceof MenuCustomItem)
                .setUrlEnabled(item instanceof MenuCustomItem));
    }
    
    public Content save(MenuItemEditForm form, int itemId) {
        MenuItem item = logic.getItem(itemId);
        if (item == null) {
            return null;
        }
        if (item instanceof MenuCustomItem) {
            if (form.getTitle() == null || form.getTitle().isEmpty()) {
                form.getValidation().add(bundle(ValidationBundle.class).titleEmpty());
            }
            if (form.getUrl() == null || form.getUrl().isEmpty()) {
                form.getValidation().add(bundle(ValidationBundle.class).urlEmpty());
            }
            if (!form.getValidation().isEmpty()) {
                return edit(form, itemId);
            }
        }
        logic.setItemTitle(itemId, form.getTitle() != null ? form.getTitle() : "");
        if (item instanceof MenuCustomItem) {
            logic.setCustomItemUrl(itemId, form.getUrl());
        }
        return edit(form, itemId);
    }
    
    public Content add(MenuItemEditForm form) {
        return html(createView(MenuItemEditView.class)
                .setForm(form)
                .setItem(null)
                .setRemovable(false)
                .setUrlEnabled(true));
    }
    
    public Content save(MenuItemEditForm form) {
        int itemId = logic.createCustomItem(form.getTitle(), form.getUrl());
        return redirect(route(MenuRoute.class).edit(itemId));
    }
    
    public Content remove(MenuEditForm form) {
        Integer itemId = form.getAffectedItemId();
        if (itemId == null) {
            return null;
        }
        MenuCustomItem item = (MenuCustomItem)logic.getItem(itemId);
        form.getSelectedItemIds().remove(itemId);
        return html(createView(AcceptRemoveMenuItemView.class)
                .setForm(form)
                .setItem(item));
    }
    
    public Content acceptRemove(MenuEditForm form) {
        Integer itemId = form.getAffectedItemId();
        if (itemId == null) {
            return null;
        }
        logic.deleteCustomItem(itemId);
        return list(form);
    }
    
    public Content remove(@SuppressWarnings("unused") MenuItemEditForm form, int itemId) {
        MenuEditForm listForm = new MenuEditForm();
        listForm.getAffectedItemIds().add(itemId);
        return remove(listForm);
    }
}
